home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Workbench Add-On
/
Workbench Add-On - Volume 1.iso
/
BBS-Archive
/
Comm
/
term-source.lha
/
Extras
/
Source
/
term-Source.lha
/
termBoxes.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-04-14
|
13KB
|
766 lines
/*
** termBoxes.c
**
** Text box management support routines
**
** Copyright © 1990-1995 by Olaf `Olsen' Barthel
** All Rights Reserved
*/
#include "termGlobal.h"
/* Sizing data. */
STATIC struct RastPort *SZ_RPort;
STATIC struct TextFont *SZ_TextFont;
STATIC struct Screen *SZ_Screen;
STATIC LONG SZ_Left,
SZ_Top,
SZ_CurrentLeft,
SZ_CurrentTop,
SZ_CurrentWidth,
SZ_MaxWidth,
SZ_TextPen,
SZ_BackPen,
SZ_LastLeft,
SZ_LastTop,
SZ_LastWidth,
SZ_LastHeight,
SZ_AverageGlyphWidth;
/* SZ_GetLeftEdge():
*
* Get the current object left edge.
*/
LONG
SZ_GetLeftEdge()
{
return(SZ_CurrentLeft);
}
/* SZ_SetTopEdge(LONG Top):
*
* Set the current object top edge.
*/
VOID __regargs
SZ_SetTopEdge(LONG Top)
{
SZ_CurrentTop = Top;
}
/* SZ_SetLeftEdge(LONG Left):
*
* Set the current object left edge.
*/
VOID __regargs
SZ_SetLeftEdge(LONG Left)
{
SZ_CurrentLeft = Left;
}
/* SZ_SetAbsoluteTop(LONG Top):
*
* Set new inner window top edge.
*/
VOID __regargs
SZ_SetAbsoluteTop(LONG Top)
{
SZ_Top = Top;
}
/* SZ_SetAbsoluteLeft(LONG Left):
*
* Set new inner window left edge.
*/
VOID __regargs
SZ_SetAbsoluteLeft(LONG Left)
{
SZ_Left = Left;
}
/* SZ_SetWidth(LONG Width):
*
* Set current object width.
*/
VOID __regargs
SZ_SetWidth(LONG Width)
{
SZ_CurrentWidth = Width;
}
/* SZ_AddLeftOffset(LONG Offset):
*
* Update current object left offset.
*/
VOID __regargs
SZ_AddLeftOffset(LONG Offset)
{
SZ_CurrentLeft += Offset;
}
/* SZ_LeftOffsetN(LONG DataArray,...):
*
* Determine the maximum length of a number of
* gadget labels (first, second, third item, -1 terminates
* the array).
*/
LONG __stdargs
SZ_LeftOffsetN(LONG DataArray,...)
{
LONG *Data = &DataArray,
Len,
Max = 0;
STRPTR String;
while(*Data != -1)
{
String = LocaleString(*Data++);
if((Len = TextLength(SZ_RPort,String,strlen(String))) > Max)
Max = Len;
}
return(Max + INTERWIDTH);
}
/* SZ_SizeCleanup():
*
* Free data allocated by SZ_SizeSetup().
*/
VOID
SZ_SizeCleanup()
{
if(SZ_TextFont)
{
CloseFont(SZ_TextFont);
SZ_TextFont = NULL;
}
if(SZ_RPort)
{
FreeVecPooled(SZ_RPort);
SZ_RPort = NULL;
}
}
/* SZ_SizeSetup(struct Screen *Screen,struct TextAttr *TextAttr):
*
* Perform setups for gadget creation.
*/
BYTE __regargs
SZ_SizeSetup(struct Screen *Screen,struct TextAttr *TextAttr)
{
SZ_SizeCleanup();
if(Screen)
{
struct DrawInfo *DrawInfo;
if(DrawInfo = GetScreenDrawInfo(Screen))
{
SZ_TextPen = DrawInfo -> dri_Pens[TEXTPEN];
SZ_BackPen = DrawInfo -> dri_Pens[BACKGROUNDPEN];
FreeScreenDrawInfo(Screen,DrawInfo);
}
}
else
{
if(!TextAttr)
return(FALSE);
}
SZ_Screen = Screen;
if(SZ_RPort = (struct RastPort *)AllocVecPooled(sizeof(struct RastPort),MEMF_ANY | MEMF_CLEAR))
{
InitRastPort(SZ_RPort);
if(!TextAttr)
TextAttr = Screen -> Font;
if(SZ_TextFont = (struct TextFont *)OpenDiskFont(TextAttr))
{
UWORD i,Width;
UBYTE Char;
InterWidth = INTERWIDTH;
if(SZ_TextFont -> tf_YSize <= 8)
InterHeight = 1;
else
InterHeight = SZ_TextFont -> tf_YSize / 4;
SetFont(SZ_RPort,SZ_TextFont);
SZ_AverageGlyphWidth = 0;
for(i = 0 ; i < 256 ; i++)
{
Char = i;
Width = TextLength(SZ_RPort,&Char,1);
SZ_AverageGlyphWidth += Width;
}
SZ_AverageGlyphWidth /= 256;
SZ_Left = InterWidth;
if(Screen)
SZ_Top = Screen -> WBorTop + Screen -> Font -> ta_YSize + 1 + InterHeight;
else
SZ_Top = 0;
SZ_CurrentLeft = InterWidth;
SZ_CurrentTop = SZ_Top;
SZ_CurrentWidth = 0;
SZ_MaxWidth = 0;
return(TRUE);
}
}
SZ_SizeCleanup();
return(FALSE);
}
/* SZ_GetLen(STRPTR String):
*
* Get the string pixel width, measured using the average
* glyph width.
*/
ULONG __regargs
SZ_GetLen(STRPTR String)
{
return(strlen(String) * SZ_AverageGlyphWidth);
}
/* SZ_FreeBox(struct TextBox *Box):
*
* Free a text box.
*/
STATIC VOID __regargs
SZ_FreeBox(struct TextBox *Box)
{
if(Box)
{
if(Box -> Text)
{
LONG i;
for(i = 0 ; i < Box -> NumLines ; i++)
{
if(Box -> Text[i])
FreeVecPooled(Box -> Text[i]);
}
FreeVecPooled(Box -> Text);
}
if(Box -> Title)
FreeVecPooled(Box -> Title);
FreeVecPooled(Box);
}
}
/* SZ_FreeBoxes(struct TextBox *FirstBox):
*
* Free a number of text boxes.
*/
VOID __regargs
SZ_FreeBoxes(struct TextBox *FirstBox)
{
if(FirstBox)
{
struct TextBox *NextBox;
do
{
NextBox = FirstBox -> NextBox;
SZ_FreeBox(FirstBox);
FirstBox = NextBox;
}
while(FirstBox);
}
}
/* SZ_BoxWidth(LONG Chars):
*
* Determine the width of a text box.
*/
LONG __regargs
SZ_BoxWidth(LONG Chars)
{
return((LONG)(4 + SZ_AverageGlyphWidth * Chars + 4));
}
/* SZ_BoxHeight(LONG Lines):
*
* Determine the height of a text box.
*/
LONG __regargs
SZ_BoxHeight(LONG Lines)
{
return(2 + SZ_TextFont -> tf_YSize * Lines + 2);
}
/* SZ_SetTitlePen(struct TextBox *Box,LONG FgPen,LONG BgPen):
*
* Set the text box list title text rendering pens.
*/
VOID __regargs
SZ_SetTitlePen(struct TextBox *Box,LONG FgPen,LONG BgPen)
{
while(Box)
{
Box -> TitleFgPen = FgPen;
Box -> TitleBgPen = BgPen;
Box = Box -> NextBox;
}
}
/* SZ_CreateTextBox(struct TextBox **FirstBox,...):
*
* Create a text box, this routine works similar
* to the CreateGadget() frontend.
*/
struct TextBox * __stdargs
SZ_CreateTextBox(struct TextBox **FirstBox,...)
{
va_list VarArgs;
struct TagItem *TagList,
*ThisTag;
LONG Chars,Lines,
Width,
Height,
Left = SZ_CurrentLeft;
BYTE AutoWidth = FALSE,
MoveDown = TRUE,
SetLeft = FALSE,
SetBelow = FALSE;
struct TextBox *Box;
LONG i;
va_start(VarArgs,FirstBox);
TagList = (struct TagItem *)VarArgs;
if(ThisTag = FindTagItem(SZ_Lines,TagList))
Lines = (LONG)ThisTag -> ti_Data;
else
return(NULL);
Height = 2 + SZ_TextFont -> tf_YSize * Lines + 2;
if(ThisTag = FindTagItem(SZ_AutoWidth,TagList))
AutoWidth = ThisTag -> ti_Data;
if(!AutoWidth)
return(NULL);
else
Chars = (SZ_CurrentWidth - 8) / SZ_AverageGlyphWidth;
if(!(Box = (struct TextBox *)AllocVecPooled(sizeof(struct TextBox),MEMF_ANY | MEMF_CLEAR)))
return(NULL);
if(ThisTag = FindTagItem(SZ_NewColumn,TagList))
{
if(ThisTag -> ti_Data)
{
SZ_CurrentTop = SZ_Top;
Left = Left + SZ_MaxWidth + InterWidth;
SZ_MaxWidth = 0;
}
}
if(ThisTag = FindTagItem(SZ_AutoWidth,TagList))
AutoWidth = ThisTag -> ti_Data;
if(!AutoWidth)
Width = SZ_BoxWidth(Chars);
else
Width = SZ_CurrentWidth;
Box -> Left = Left;
Box -> Top = SZ_CurrentTop;
Box -> Width = Width;
Box -> Height = Height;
Box -> LineWidth = Chars * SZ_AverageGlyphWidth;
Box -> LineHeight = SZ_TextFont -> tf_YSize;
Box -> NumChars = Chars;
Box -> NumLines = Lines;
Box -> TitleFgPen = SZ_TextPen;
Box -> TitleBgPen = SZ_BackPen;
Box -> TextPen = SZ_TextPen;
if(!(Box -> Title = (STRPTR *)AllocVecPooled(sizeof(STRPTR) * Lines,MEMF_ANY | MEMF_CLEAR)))
{
SZ_FreeBox(Box);
return(NULL);
}
if(!(Box -> Text = (STRPTR *)AllocVecPooled(sizeof(STRPTR) * Lines,MEMF_ANY | MEMF_CLEAR)))
{
SZ_FreeBox(Box);
return(NULL);
}
for(i = 0 ; i < Lines ; i++)
{
if(!(Box -> Text[i] = (STRPTR)AllocVecPooled(Chars + 1,MEMF_ANY | MEMF_CLEAR)))
{
SZ_FreeBox(Box);
return(NULL);
}
}
if(SetBelow)
MoveDown = FALSE;
if(MoveDown)
SZ_CurrentTop = SZ_CurrentTop + Height + InterHeight;
else
SZ_MaxWidth = 0;
if(Width > SZ_MaxWidth)
SZ_MaxWidth = Width;
if(!SetLeft)
SZ_CurrentLeft = Left;
if(!(*FirstBox))
*FirstBox = Box;
else
{
struct TextBox *CurrentBox = *FirstBox;
while(CurrentBox -> NextBox)
CurrentBox = CurrentBox -> NextBox;
CurrentBox -> NextBox = Box;
}
return(Box);
}
/* SZ_SetBoxTitles(struct TextBox *Box,STRPTR Array,...):
*
* Set the titles displayed in a text box.
*/
VOID __stdargs
SZ_SetBoxTitles(struct TextBox *Box,STRPTR Array,...)
{
if(Box)
{
STRPTR *Data = &Array;
LONG i = 0;
while(*Data != NULL)
{
if(i < Box -> NumLines)
Box -> Title[i++] = *Data;
Data++;
}
}
}
/* SZ_SetLine():
*
* Print a string into a text box, plain version.
*/
VOID __regargs
SZ_SetLine(struct RastPort *RPort,struct TextBox *Box,LONG Line,STRPTR String)
{
BYTE FgPen = ReadAPen(RPort),
BgPen = ReadBPen(RPort),
DrMd = ReadDrMd(RPort);
struct TextFont *Font = RPort -> Font;
LONG Width,Len,
Left = Box -> Left + 4,
Top = Box -> Top + 2 + Line * Box -> LineHeight;
if(DrMd != JAM2)
SetDrMd(RPort,JAM2);
if(FgPen != Box -> TextPen)
SetAPen(RPort,Box -> TextPen);
if(BgPen != SZ_BackPen)
SetBPen(RPort,SZ_BackPen);
if(Font != UserTextFont)
SetFont(RPort,UserTextFont);
if(Len = strlen(String))
{
if(Len > Box -> NumChars)
Len = Box -> NumChars;
while(Len > 0 && TextLength(RPort,String,Len) > Box -> LineWidth)
Len--;
if(Len)
{
Width = TextLength(RPort,String,Len);
Move(RPort,Left,Top + RPort -> Font -> tf_Baseline);
Text(RPort,String,Len);
}
else
Width = 0;
}
else
Width = 0;
if(Width != Box -> LineWidth)
{
if(FgPen != SZ_BackPen)
{
SetAPen(RPort,SZ_BackPen);
RectFill(RPort,Left + Width,Top,Left + Box -> LineWidth - 1,Top + Box -> LineHeight - 1);
SetAPen(RPort,FgPen);
}
else
RectFill(RPort,Left + Width,Top,Left + Box -> LineWidth - 1,Top + Box -> LineHeight - 1);
}
if(DrMd != JAM2)
SetDrMd(RPort,DrMd);
if(String != Box -> Text[Line])
{
if(Len > 0)
CopyMem(String,Box -> Text[Line],Len);
Box -> Text[Line][Len] = 0;
}
if(Font != UserTextFont)
SetFont(RPort,Font);
if(BgPen != SZ_BackPen)
SetBPen(RPort,BgPen);
SetAPen(RPort,FgPen);
}
/* SZ_PrintLine():
*
* Print a string into a text box, varargs version.
*/
VOID __stdargs
SZ_PrintLine(struct RastPort *RPort,struct TextBox *Box,LONG Line,STRPTR String,...)
{
va_list VarArgs;
UBYTE Buffer[256];
va_start(VarArgs,String);
VSPrintf(Buffer,String,VarArgs);
va_end(VarArgs);
SZ_SetLine(RPort,Box,Line,Buffer);
}
/* SZ_DrawBox(struct RastPort *RPort,struct TextBox *Box):
*
* (Re-)Draw a text box.
*/
STATIC VOID __regargs
SZ_DrawBox(struct RastPort *RPort,struct TextBox *Box)
{
if(Box)
{
LONG LineY,i,Len,FgPen = ReadAPen(RPort),BgPen = ReadBPen(RPort),DrMd = ReadDrMd(RPort);
struct TextFont *Font = RPort -> Font;
if(Font != UserTextFont)
SetFont(RPort,UserTextFont);
if(FgPen != SZ_BackPen)
{
SetAPen(RPort,SZ_BackPen);
RectFill(RPort,Box -> Left,Box -> Top,Box -> Left + Box -> Width - 1,Box -> Top + Box -> Height - 1);
SetAPen(RPort,FgPen);
}
else
RectFill(RPort,Box -> Left,Box -> Top,Box -> Left + Box -> Width - 1,Box -> Top + Box -> Height - 1);
DrawBevelBox(RPort,Box -> Left,Box -> Top,Box -> Width,Box -> Height,
GT_VisualInfo, VisualInfo,
GTBB_Recessed, TRUE,
TAG_DONE);
LineY = Box -> Top + 2 + RPort -> Font -> tf_Baseline;
SetAPen(RPort,Box -> TitleFgPen);
SetBPen(RPort,Box -> TitleBgPen);
SetDrMd(RPort,JAM2);
for(i = 0 ; i < Box -> NumLines ; i++)
{
if(Len = strlen(Box -> Title[i]))
{
Move(RPort,Box -> Left - INTERWIDTH - TextLength(RPort,Box -> Title[i],Len),LineY);
Text(RPort,Box -> Title[i],Len);
}
LineY += Box -> LineHeight;
}
for(i = 0 ; i < Box -> NumLines ; i++)
SZ_PrintLine(RPort,Box,i,Box -> Text[i]);
SetAPen(RPort,FgPen);
SetBPen(RPort,BgPen);
SetDrMd(RPort,DrMd);
if(Font != UserTextFont)
SetFont(RPort,Font);
}
}
/* SZ_DrawBoxes(struct RastPort *RPort,struct TextBox *FirstBox):
*
* (Re-)Draw a number of text boxes.
*/
VOID __regargs
SZ_DrawBoxes(struct RastPort *RPort,struct TextBox *FirstBox)
{
do
SZ_DrawBox(RPort,FirstBox);
while(FirstBox = FirstBox -> NextBox);
}
/* SZ_MoveBox(struct TextBox *Box,LONG Left,LONG Top):
*
* Change the location of a text box.
*/
STATIC VOID __regargs
SZ_MoveBox(struct TextBox *Box,LONG Left,LONG Top)
{
Box -> Left += Left;
Box -> Top += Top;
}
/* SZ_MoveBoxes(struct TextBox *FirstBox,LONG Left,LONG Top):
*
* Change the locations of a number of text boxes.
*/
VOID __regargs
SZ_MoveBoxes(struct TextBox *FirstBox,LONG Left,LONG Top)
{
do
SZ_MoveBox(FirstBox,Left,Top);
while(FirstBox = FirstBox -> NextBox);
}
/* SZ_SetBox(struct TextBox *Box,LONG Left,LONG Top):
*
* Set the location of a text box.
*/
STATIC VOID __regargs
SZ_SetBox(struct TextBox *Box,LONG Left,LONG Top)
{
if(Left >= 0)
Box -> Left = Left;
if(Top >= 0)
Box -> Top = Top;
}
/* SZ_SetBoxes(struct TextBox *FirstBox,LONG Left,LONG Top):
*
* Set the locations of a number of text boxes.
*/
VOID __regargs
SZ_SetBoxes(struct TextBox *FirstBox,LONG Left,LONG Top)
{
do
SZ_SetBox(FirstBox,Left,Top);
while(FirstBox = FirstBox -> NextBox);
}
/* SZ_GetBoxInfo(struct TextBox *Box,LONG Type):
*
* Query information on a certain text box.
*/
LONG __regargs
SZ_GetBoxInfo(struct TextBox *Box,LONG Type)
{
switch(Type)
{
case BOX_LEFT:
return(Box -> Left);
case BOX_TOP:
return(Box -> Top);
case BOX_WIDTH:
return(Box -> Width);
case BOX_HEIGHT:
return(Box -> Height);
default:
return(0);
}
}